--[[
Name: BrownieHelper
Developed by: Sonora (The Dragon Flight)
Website: http://sonora.kirintor.googlepages.com/contents
SVN: http://code.google.com/p/browniehelper/source/browse
License: GNU General Public License v3
]]

--[[
Overview

This module provides an implementation of The Dragonflight's Beny's Brownie
Points loot bidding system for the BrownieHelper addon.  If you want to tweak
the bidding system, use this module as a template.

To implement your own bidding system using BrownieHelper:
1)  Use this module as a template to tweak the bidding setup and logic so that
it continues to provide the basic interface outlined below
2)  Remove this module from the list of includes in your .toc file and replace
it with your own.

See biddingsystems.lua for more information about what a bidding system is and
how you can plug new ones into BrownieHelper.
]]--


--Custom bidding systems
local brownieSystems = {
    --These are the systems used by the standard Beny's Brownie Points implementation
    
    --[[
    In BBP the first phase extends the rules of a simple auction with:
        1.  requires players have >= 0 points to place a minimum bid
        2.  players can't win the first phase more than once per run
    ]]
    ["First phase"] = {
        minbid = function(charactername, bidsetup)
            --if the player has >=0 points, the answer is the minimum bid in the bidsetup
            if getPlayerPoints(charactername, bidsetup) >= 0 then return bidsetup.minbid
            --otherwise, they can't bid
            else return nil
            end
        end,
        maxbid = getPlayerMaxBid,
        checkBid = function(bid, bidsetup)
            --We add a check to make sure the player hasn't won in the first phase yet
            local runName, runDb = bidsetup.app:getCurrentRun()
            local winlist = runDb.firstPhaseWins
            if winlist ~=nil and has(winlist, bid.charactername) then
                return false, "I can't accept your bid because you have already won a first phase bid durring this run.  You can bid on the item if it progresses to the second phase."
            end
        end,
        findWinner = progressiveFindWinner,
        registerWinner = function(winningbid, bidsetup)
            --We save a database entry to remember that this player has won a first phase bid on this run
            local runName, runDb = bidsetup.app:getCurrentRun()
            if runDb.firstPhaseWins==nil then runDb.firstPhaseWins={} end
            table.insert(runDb.firstPhaseWins, winningbid.charactername)
        end,
        instructions = "First phase is the first of two need rounds.  Unlike the second phase, there are two restrictions: you can only win one first phase auction per run, and you must have at least 0 points to bid.",
    },
    
    --[[
    The stock Simple Auction in biddingsystems perfectly describes the BBP
    second phase...
    ]]
    ["Second phase"] = {
        minbid = function(charactername, bidsetup) return bidsetup.minbid end,
        maxbid = getPlayerMaxBid,
        findWinner = progressiveFindWinner,
        instructions = "Second phase is the second of two need rounds.  This is your last chance to bid on the item if it is an upgrade for your primary role.",
    },
    
    ["Third phase"] = {
        minbid = function(charactername, bidsetup)
            --if the player has >=0 points, the answer is 1
            if getPlayerPoints(charactername, bidsetup) >= 0 then return 1
            --otherwise, they can't bid... the ML can always force a 1 pt bid if no one interested has more than 0 points (as stated in the rules)
            else return nil
            end
        end,
        maxbid = getPlayerMaxBid,
        findWinner = function(bids, bidsetup) return progressiveFindWinner(bids, bidsetup, 1) end,
        instructions = "Third phase is the greed round.  You can bid on the item now for any game play use (RP doesn't count), even if its not for your primary role.",
    },
    
    ["Fourth phase"] = {
        minbid = function() return 0 end,
        maxbid = function() return 0 end,
        findWinner = function(bids, bidsetup)
            --Just check rolls
            winningbid, possible_winners = findRollWinner(bids, bidsetup)
            return winningbid, (possible_winners~=nil and "The following players should roll off:\n\n"..valueJoin(fromValues(possible_winners,'charactername'),"\n") or "")
        end,
        instructions = "Fourth phase is normally the shard round, but you can opt to take items durring this phase in exchange for donating a void crystal to the bank.",
    },
    
    ["BOP reagents"] = {
        minbid = function() return 1 end,
        maxbid = function() return nil end,
        findWinner = function(bids, bidsetup)
            winningbid, response = progressiveFindWinner(bids, bidsetup, 1)
            
            if winningbid~=nil then
                
                --Create a call back that will adjust the winning bid based on how many of the item the player wants
                response_callback = function(input_text)
                    new_value = tonumber(input_text) * winningbid.bid
                    winningbid.bid = new_value
                    winningbid.update()
                end
                
                --Ask how many items the player wants to bid on at the current point level
                inputDialog("Enter the number of "..bidsetup.itemname.." that "..winningbid.charactername.." wants (cost is "..tostring(winningbid.bid).." each)", response_callback, 1)
                
                --Return what we have for now...
                return winningbid, "Total bid pending update... (when we find out how many items the player wanted)"
                
            else return winningbid, response
            end
            
        end,
        instructions = "Place a bid based on how many points you're willing to spend for *each* item you want.  For example, you want 3 vortexes for 5 points each, please bid 5 points (and you will be charged 15 if you win).",
    },
    
    ["BOP item recipes"] = {
        minbid = function() return 4 end,
        maxbid = function() return 4 end,
        findWinner = function(bids, bidsetup)
            --Just check rolls
            winningbid, possible_winners = findRollWinner(bids, bidsetup)
            return winningbid, (possible_winners~=nil and "The following players should roll off:\n\n"..valueJoin(fromValues(possible_winners,'charactername'),"\n") or "")
        end,
        instructions = "Recipes that make BoP items cost a flat 4 points.  Bid now if you are interested and then roll off if necessary.",
    },
    
    ["BOE crafting materials"] = {
        minbid = function() return 2 end,
        maxbid = function() return 2 end,
        findWinner = function(bids, bidsetup)
            --Just check rolls
            winningbid, possible_winners = findRollWinner(bids, bidsetup)
            return winningbid, (possible_winners~=nil and "The following players should roll off:\n\n"..valueJoin(fromValues(possible_winners,'charactername'),"\n") or "")
        end,
        instructions = "BOP crafting items cost a flat 2 points.  Bid now if you are interested and then roll off if necessary.",
    },
    
    ["BOE item recipes"] = {
        minbid = function() return 0 end,
        maxbid = function() return 0 end,
        findWinner = function(bids, bidsetup)
            --Just check rolls
            winningbid, possible_winners = findRollWinner(bids, bidsetup)
            return winningbid, (possible_winners~=nil and "The following players should roll off:\n\n"..valueJoin(fromValues(possible_winners,'charactername'),"\n") or "")
        end,
        instructions = "Recipes that make BoE items don't cost any points.  Roll now if you are a full member and can craft the item."
    },
}

--register all of our bidding systems
for systemName, system in pairs(brownieSystems) do registerBiddingSystem(systemName,system) end


